#include "../Base.h"
#pragma warning(disable:4996)
VOID tests() {

}




EXTERN_C WCHAR* GetSystemRootNtdllPath( )
{

	//��ȡ��Ŀ¼
	PKUSER_SHARED_DATA share_user_data =
		static_cast<PKUSER_SHARED_DATA>(SharedUserData);

	WCHAR* systemPath;
	systemPath = 
		static_cast<WCHAR*>(ExAllocatePoolWithTag(PagedPool, PAGE_SIZE,'yang'));
	memset(systemPath, 0, PAGE_SIZE);
	RtlStringCbPrintfW(
		systemPath,
		PAGE_SIZE,
		L"\\??\\%s\\system32\\ntdll.dll",
		share_user_data->NtSystemRoot
	);

	return systemPath;
}


PVOID MapOfSection(WCHAR* path)
{

	HANDLE hFile = NULL;
	OBJECT_ATTRIBUTES object_attributes;
	UNICODE_STRING file_name;
	RtlInitUnicodeString(&file_name, path);
	IO_STATUS_BLOCK io_status_block = { 0 };

	
	InitializeObjectAttributes(
		&object_attributes,
		&file_name,
		OBJ_CASE_INSENSITIVE,
		NULL, NULL,
		);
	NTSTATUS status = ZwCreateFile(
		&hFile, FILE_READ_DATA,
		&object_attributes,
		&io_status_block, NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN,
		FILE_NON_DIRECTORY_FILE
		| FILE_SYNCHRONOUS_IO_NONALERT,
		NULL, NULL
	);

	if(!NT_SUCCESS(status))
	{
		ZwClose(hFile);
	}


	PVOID section_object;
	OBJECT_ATTRIBUTES section_attribute;
	InitializeObjectAttributes(
		&section_attribute,
		NULL,
		OBJ_CASE_INSENSITIVE,
		NULL, NULL,
		);
	LARGE_INTEGER InputMaxmumSize = { 0 };
	//������������
	status = MmCreateSection(
		&section_object,
		SECTION_ALL_ACCESS,
		NULL, &InputMaxmumSize,PAGE_EXECUTE_READWRITE,
		0x1000000,
		hFile,
		NULL
	);
	if(!NT_SUCCESS(status))
	{
		ZwClose(section_object);
	}
	PVOID mapBase = NULL;
	SIZE_T viewsize = { 0 };
	//ӳ�䵽ϵͳ�ڴ�  ���Զ�չ��
	status = MmMapViewInSystemSpace(section_object, &mapBase, &viewsize);
	ObDereferenceObject(section_object);
	
	if(NT_SUCCESS(status))
	{
		return mapBase;
	}
	return NULL;
}

VOID UnMapOfSection(PVOID pMapBase)
{
	if(!pMapBase)
	MmUnmapViewInSystemSpace(pMapBase);

}

PVOID RVATOVA(PVOID _base_, PVOID _offset_)
{
	return ((PUCHAR)(_base_)+(ULONG)(_offset_));
}

ULONG_PTR GetProcAddress_FromPEExport(PVOID Image,char* FunctionName)
{

	__try
	{
		PIMAGE_EXPORT_DIRECTORY pExport = NULL;

		PIMAGE_NT_HEADERS32 pHeaders32 = (PIMAGE_NT_HEADERS32)
			((PUCHAR)Image + ((PIMAGE_DOS_HEADER)Image)->e_lfanew);

		if (pHeaders32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
		{
			// 32-bit image
			if (pHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
			{
				pExport = (PIMAGE_EXPORT_DIRECTORY)RVATOVA(
					Image,
					PVOID(pHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
				);
			}
		}
		else if (pHeaders32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
		{
			// 64-bit image
			PIMAGE_NT_HEADERS64 pHeaders64 = (PIMAGE_NT_HEADERS64)
				((PUCHAR)Image + ((PIMAGE_DOS_HEADER)Image)->e_lfanew);

			if (pHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
			{
				pExport = (PIMAGE_EXPORT_DIRECTORY)RVATOVA(
					Image,
					PVOID(pHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
				);
			}
		}

		

		if (pExport)
		{
			PULONG AddressOfFunctions = (PULONG)RVATOVA(Image, PVOID(pExport->AddressOfFunctions));
			PSHORT AddrOfOrdinals = (PSHORT)RVATOVA(Image, PVOID(pExport->AddressOfNameOrdinals));
			PULONG AddressOfNames = (PULONG)RVATOVA(Image, PVOID(pExport->AddressOfNames));
			ULONG i = 0;
			for (i = 0; i < pExport->NumberOfFunctions; i++)
			{
			
				if (!strcmp((char*)RVATOVA(Image, PVOID(AddressOfNames[i])), FunctionName))
				{
					
					return (ULONG_PTR)RVATOVA(Image, PVOID(AddressOfFunctions[AddrOfOrdinals[i]]));
				
				}
			}
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER) {}
	return 0;
}


